home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
satellit
/
pbsv004
/
pbsv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-05
|
13KB
|
653 lines
/* pbsv.c 1993.8.6 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* #include <io.h> */
#include <time.h>
#include <sys/stat.h>
#include "pbsv.h"
extern int svcfg(); /* pbcfg.c */
extern VOID dspinfo();
extern int initdir(); /* pbdir.c */
extern VOID qst_dir();
extern int req_dir();
extern int pfhstat(char*,struct stpfh*);
extern VOID cmd(); /* pbcmd.c */
extern VOID initq(),putq(); /* pblib.c */
extern VOID delq();
extern struct stqcell *getq();
extern VOID ca2ad(),ad2ca();
extern int ckcrc();
extern int calc_crc(); /* crc.c */
extern VOID inikss(),exitkss(); /* pbkiss.c */
extern VOID rcvkss(),sndkss();
extern BOOL f_rkss,f_skss;
extern int lnrkss,lnskss;
extern char rkss[],skss[];
struct stuser user[MAXUSER];
struct sthole hole[MAXHOLE];
struct stqueue actuser;
struct stqueue freeuser;
struct stqueue freehole;
/* pbdv config data */
char cfgfile[128] = {"pbsv.cfg"};
char bdcall[CALLSIZE];
char bdadrs[ADRSIZE];
int port = 0; /* COM1 */
/* kiss mode parm */
int txd = 300;
int persist = NOT_DEFINE;
int slottime = NOT_DEFINE;
int txtail = NOT_DEFINE;
int fullduplex = NOT_DEFINE;
int sethardware = NOT_DEFINE;
int softdcd = NOT_DEFINE;
int kissrom = 0;
int multikiss = 0;
char dldir[128];
char hdrqst[HDRSIZE]; /* QST-1 header pid = bb */
char hdrdqst[HDRSIZE]; /* QST-1 directory header pid = pd */
char hdrpblst[HDRSIZE]; /* PBLIST header */
char hdrokno[HDRSIZE]; /* OK / NO */
char hdreq[HDRSIZE]; /* request pid = bb */
/* flags */
BOOL f_debug = OFF;
BOOL f_exit = OFF;
BOOL f_beacon = OFF;
BOOL f_verbose = OFF;
BOOL f_headers = OFF;
BOOL f_hex = OFF;
clock_t tim_0; /* timer PBLIST */
clock_t tim_1,tim_2;
clock_t tim_3; /* exit timer */
BOOL f_etim = OFF;
long exit_timer = 60*30;
/*
* < main > main
*/
VOID main(argc,argv)
int argc;
char *argv[];
{
VOID initsv(),pbsv();
int i,n;
printf("*** Broadcast Server ***\n");
printf("PBSV ver%s%s",PBSV_VER,PBSV_ID);
printf(" by N.Okamoto JN2LHU @ JN2BDS.19.JNET2.JPN.AS\n");
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
switch(argv[i][1]) {
case 'v': case 'V':
f_verbose = ON;
break;
case 'q': case 'Q':
f_exit = ON;
break;
case 's': case 'S':
exit_timer = (clock_t)atol(&argv[i][2]);
f_etim = ON;
break;
default:
if (strcmp(&argv[i][1],"debug") == 0) {
f_debug = ON;
}
break;
}
} else {
strcpy(cfgfile,argv[i]);
}
}
svcfg();
initsv();
n = initdir();
if (n == 0) {
printf("Error: DL files not exist\n");
exit(1);
}
pbsv();
}
/*
* < initsv > init pbsv
*/
VOID initsv()
{
char *p;
int i;
initq(&actuser);
initq(&freeuser);
for (i = 0; i < MAXUSER; i++) {
putq(&freeuser,&user[i]);
}
initq(&freehole);
for (i = 0; i < MAXHOLE; i++) {
putq(&freehole,&hole[i]);
}
hdrqst[0] = (multikiss<<4);
ca2ad("QST-1",hdrqst+1);
memcpy(hdrqst+1+ADRSIZE,bdadrs,ADRSIZE);
hdrqst[7] &= 0x1f; /* C,RR not used */
hdrqst[14] &= 0x1f;
hdrqst[14] |= 0x01;
hdrqst[15] = 0x03; /* UI */
hdrqst[16] = 0xbb; /* PID = BB */
memcpy(hdrokno,hdrqst,HDRSIZE);
hdrokno[16] = 0xf0;
memcpy(hdrdqst,hdrqst,HDRSIZE);
hdrdqst[16] = 0xbd; /* PID = BD */
memcpy(hdrpblst,hdrqst,HDRSIZE);
ca2ad("PBLIST",hdrpblst+1);
hdrpblst[16] = 0xf0; /* PID = F0 */
p = hdreq;
p[0] = 0x00;
memcpy(p+1,bdadrs,7);
p[7] &= 0x1f; /* C,RR not used */
p[14] &= 0x1f;
p[14] |= 0x01;
p[15] = 0x03; /* UI */
p[16] = 0xbb; /* PID = BB */
}
/*
* < pbsv > PB-server
*/
VOID pbsv()
{
VOID timer(),qst(),pblist(int);
VOID rcvreq();
timer();
tim_3 = exit_timer;
inikss();
for (;;) {
cmd();
timer();
pblist(0);
qst();
rcvreq();
rcvkss();
if (f_etim && tim_3 == 0) {
f_exit = ON;
if (f_verbose)
printf("exit timer count up\n");
}
if (f_exit) {
break;
}
}
exitkss();
}
/*
* < timer > timer
*/
VOID timer()
{
static clock_t t1;
clock_t clk,t;
clk = clock();
t = clk - t1;
t1 = clk;
if ((u_long)tim_0 > (u_long)t) {
tim_0 -= t;
} else
tim_0 = 0;
if ((u_long)tim_1 > (u_long)t) {
tim_1 -= t;
} else
tim_1 = 0;
if ((u_long)tim_2 > (u_long)t) {
tim_2 -= t;
} else
tim_2 = 0;
if ((u_long)tim_3 > (u_long)t) {
tim_3 -= t;
} else
tim_3 = 0;
}
/*
* < pblist > PB list
*/
VOID pblist(ctl)
int ctl;
{
VOID add_kss(char*,int);
char buf[256];
int n;
struct stuser *user;
if (f_beacon) {
f_beacon = OFF;
tim_0 = 0;
}
if (ctl == 1)
tim_0 = 0;
else {
if (tim_0 != 0 || actuser.head != NULL)
return;
}
if (tim_0 != 0)
return;
tim_0 = 30;
strcpy(buf,"PB:");
user = (struct stuser *)actuser.head;
n = 0;
if (user == NULL) {
strcat(buf," Empty.");
} else {
while(user != NULL) {
strcat(buf," ");
strcat(buf,user->call);
if (user->flags & F_DIR)
strcat(buf,"\\D");
user = user->next;
n++;
}
}
printf("PBLIST: %s\n",buf);
lnskss = 0;
add_kss(hdrpblst,HDRSIZE);
add_kss(buf,strlen(buf));
sndkss();
}
/*
* < qst >
*/
VOID qst()
{
VOID qst_bul();
VOID del_user(struct stuser*);
struct stuser *user;
if (actuser.head == NULL)
return;
pblist(1);
user = (struct stuser *)getq(&actuser);
/* check time over ? */
if ((u_long)(clock() - user->entry_t) > (u_long)180) {
if (f_verbose) {
printf("Delete %s in PBLIST\n",user->call);
}
del_user(user);
return;
}
if (user->flags & F_DIR) {
qst_dir(user);
} else {
qst_bul(user);
}
if (user->hole.head == NULL) {
putq(&freeuser,user);
} else {
putq(&actuser,user);
}
if (actuser.head == NULL) {
f_beacon = ON;
}
}
/*
* < qst_bul >
*/
VOID qst_bul(user)
struct stuser *user;
{
char *dlname(long);
VOID add_kss(char*,int),add_crc();
struct sthole *hole;
char name[128];
char buf[256];
FILE *fp;
char flags,file_type;
long file_id,offset;
int i;
u_int size;
file_id = user->file_id;
file_type = user->file_type;
strcpy(name,dlname(file_id));
if ((fp = fopen(name,"rb")) == NULL) {
printf("QST-1 file[%s] open error\n",name);
exit(1);
}
flags = 0x02;
for (i = 0; i < 5; i++) {
hole = (struct sthole *)user->hole.head;
if (hole == NULL)
break;
offset = hole->offset;
if (user->block_size > hole->length) {
size = hole->length;
} else {
size = user->block_size;
}
hole->offset += (long)size;
hole->length -= size;
if (hole->length == 0) {
hole = (struct sthole *)getq(&user->hole);
putq(&freehole,hole);
}
printf("QST-1: %lx msg offset=%ld,len=%d\n",file_id,offset,size);
fseek(fp,offset,SEEK_SET);
fread(buf,size,1,fp);
lnskss = 0;
add_kss(hdrqst,HDRSIZE);
add_kss(&flags,1);
add_kss((char*)&file_id,4);
add_kss(&file_type,1);
add_kss((char*)&offset,3);
add_kss(buf,size);
add_crc();
sndkss();
}
fclose(fp);
}
VOID add_kss(p,n)
char *p;
int n;
{
while(n-- > 0) {
skss[lnskss++] = *p++;
}
}
VOID add_crc()
{
int j,crc;
for (j = HDRSIZE, crc = 0; j < lnskss; j++)
crc = calc_crc(skss[j],crc);
skss[lnskss++] = (crc >> 8) & 0xff;
skss[lnskss++] = crc & 0xff;
ckcrc(skss,lnskss);
}
/*
* < rcvreq > recive request
*/
VOID rcvreq()
{
int req_bul();
VOID res_msg(char*,int);
struct stuser *sch_user(char*);
VOID del_user(struct stuser*);
char callsign[10];
int r,i;
u_char pid;
if (!f_rkss)
return;
f_rkss = OFF;
if (lnrkss <= HDRSIZE)
return;
for (i = 0; i < HDRSIZE-1; i++) {
if (i >= (1+ADRSIZE) && i < (1+ADRSIZE+ADRSIZE)) {/* skip src adrs */
;
} else if ((rkss[i] & 0xff) != (hdreq[i] & 0xff)) {
return;
}
}
pid = rkss[i];
ad2ca(rkss+1+ADRSIZE,callsign);
del_user(sch_user(callsign));
switch(pid) {
case 0xbb: /* pid = bb */
r = req_bul(callsign);
break;
case 0xbd: /* pid = bd */
r = req_dir(callsign);
break;
default:
printf("Error: rcv frame error\n");
return;
}
res_msg(callsign,r);
}
/*
* < res_msg > response messages
*/
VOID res_msg(callsign,errorcode)
char *callsign;
int errorcode;
{
char buf[64];
if (errorcode == 0) {
sprintf(buf,"OK %s\r",callsign);
} else {
sprintf(buf,"NO %d %s\r",errorcode,callsign);
}
lnskss = 0;
add_kss(hdrokno,HDRSIZE);
ca2ad(callsign,skss+1);
add_kss(buf,strlen(buf));
sndkss();
}
/*
* < req_bul > request
*/
int req_bul(callsign)
char *callsign;
{
int set_user(struct stuser*,char*,long,u_int);
int add_hole(struct stuser*,long,u_int);
char *dlname(long);
u_char flags;
long file_id,offset;
u_int block_size,length;
int i;
struct stuser *user;
i = HDRSIZE;
flags = rkss[i];
i += 1;
memcpy(&file_id,&rkss[i],4);
i += 4;
memcpy(&block_size,&rkss[i],2);
i += 2;
if (access(dlname(file_id),00) != 0) { /* DL file exist ? */
return(-2); /* file does not exist */
}
user = (struct stuser *)getq(&freeuser);
if (user == NULL) {
return(-1); /* queue full */
}
switch(flags & 0x03) {
case 0x00: /* start */
printf("%s: Start, msg %lx, %d byte frames.\n",
callsign,file_id,block_size);
set_user(user,callsign,file_id,block_size);
offset = 0;
length = block_size * 10;
for (i = 0; i < 10; i++) {
add_hole(user,offset,length);
offset += length;
}
break;
case 0x01: /* stop */
printf("%s: Stop, msg %lx.\n",callsign,file_id);
break;
case 0x02: /* hole list */
printf("%s: Fill, msg %lx, %d byte frames.\n",
callsign,file_id,block_size);
set_user(user,callsign,file_id,block_size);
for ( ; i < lnrkss; i += (3+2)) {
offset = 0;
memcpy(&offset,&rkss[i],3);
memcpy(&length,&rkss[i+3],2);
add_hole(user,offset,length);
printf(" offset: %06lx length:%04x\n",offset,length);
}
break;
default:
return(-4); /* debug */
break;
}
return(0); /* OK */
}
/*
* < set_user > set user list
*/
int set_user(user,callsign,file_id,block_size)
struct stuser *user;
char *callsign;
long file_id;
u_int block_size;
{
char *dlname(long);
struct stat sbuf;
struct stpfh pfh;
char pathname[128];
strcpy(pathname,dlname(file_id));
stat(pathname,&sbuf);
pfhstat(pathname,&pfh);
user->entry_t = clock();
user->flags = 0x0000;
strcpy(user->call,callsign);
user->file_id = file_id;
user->file_type = pfh.file_type;
user->file_size = sbuf.st_size;
if (block_size > MAXBLKSIZE) { /* block size adjust */
user->block_size = MAXBLKSIZE;
} else {
user->block_size = block_size;
}
initq(&user->hole);
putq(&actuser,user);
}
/*
* < add_hole >
*/
int add_hole(user,offset,length)
struct stuser *user;
long offset;
u_int length;
{
struct sthole *hole;
if (offset >= user->file_size)
return;
if (offset + length > user->file_size) /* adjust */
length = user->file_size - offset;
hole = (struct sthole *)getq(&freehole);
if (hole == NULL) {
assert(0);
}
hole->offset = offset;
hole->length = length;
putq(&user->hole,hole);
}
/*
* < sch_user > search user
*/
struct stuser *sch_user(callsign)
char *callsign;
{
struct stuser *user;
user = (struct stuser *)actuser.head;
while(user) {
if (strcmp(user->call,callsign) == 0) {
break;
}
user = (struct stuser *)user->next;
}
return(user);
}
/*
* < del_user > delete user
*/
VOID del_user(user)
struct stuser *user;
{
struct sthole *hole;
if (user == NULL)
return;
while(hole = (struct sthole *)getq(&user->hole)) {
putq(&freehole,hole);
}
delq(&actuser,user);
putq(&freeuser,user);
}
/*
* < dlname > pathname DL file
*/
char *dlname(file_id)
long file_id;
{
static char pathname[128];
sprintf(pathname,"%s%lx.DL",dldir,file_id);
return(pathname);
}
/* pbsv.c */